/**
 * 题库数学验证工具
 * 
 * 功能：
 * 1. 检查所有题目的答案是否正确
 * 2. 验证数学计算
 * 3. 检查题目完整性
 * 4. 生成验证报告
 */

const fs = require('fs');
const path = require('path');

// 验证结果
const results = {
  total: 0,
  passed: 0,
  failed: 0,
  warnings: 0,
  errors: [],
  warnings: [],
};

// 数学验证函数
const mathVerifiers = {
  // 鸡兔同笼验证
  chickenRabbit: (question) => {
    const match = question.stem.match(/共有头(\d+)个.*脚(\d+)只/);
    if (!match) return { valid: true, message: '无法解析题目' };
    
    const heads = parseInt(match[1]);
    const feet = parseInt(match[2]);
    const answer = parseInt(question.answer[0]);
    
    // 验证：鸡数 = (4*头数 - 脚数) / 2
    const expectedChicken = (4 * heads - feet) / 2;
    const expectedRabbit = heads - expectedChicken;
    
    if (Math.abs(answer - expectedChicken) < 0.01 || Math.abs(answer - expectedRabbit) < 0.01) {
      return { valid: true };
    }
    
    return {
      valid: false,
      message: `答案错误：头${heads}个，脚${feet}只，应该是鸡${expectedChicken}只或兔${expectedRabbit}只，但答案是${answer}`
    };
  },
  
  // 行程问题验证
  distance: (question) => {
    // 提取速度、时间、距离
    const speedMatch = question.stem.match(/速度.*?(\d+(?:\.\d+)?)\s*(?:千米\/小时|km\/h|米\/秒|m\/s)/);
    const timeMatch = question.stem.match(/时间.*?(\d+(?:\.\d+)?)\s*(?:小时|分钟|秒)/);
    const distanceMatch = question.stem.match(/距离.*?(\d+(?:\.\d+)?)\s*(?:千米|米|km|m)/);
    
    if (!speedMatch || !timeMatch) return { valid: true, message: '无法解析题目' };
    
    const speed = parseFloat(speedMatch[1]);
    const time = parseFloat(timeMatch[1]);
    const answer = parseFloat(question.answer[0]);
    
    // 距离 = 速度 × 时间
    const expectedDistance = speed * time;
    
    if (Math.abs(answer - expectedDistance) < 0.01) {
      return { valid: true };
    }
    
    return {
      valid: false,
      message: `答案错误：速度${speed}，时间${time}，距离应该是${expectedDistance}，但答案是${answer}`
    };
  },
  
  // 面积计算验证
  area: (question) => {
    // 长方形面积
    const rectMatch = question.stem.match(/长.*?(\d+(?:\.\d+)?)\s*(?:厘米|米|cm|m).*?宽.*?(\d+(?:\.\d+)?)\s*(?:厘米|米|cm|m)/);
    if (rectMatch) {
      const length = parseFloat(rectMatch[1]);
      const width = parseFloat(rectMatch[2]);
      const answer = parseFloat(question.answer[0]);
      const expectedArea = length * width;
      
      if (Math.abs(answer - expectedArea) < 0.01) {
        return { valid: true };
      }
      
      return {
        valid: false,
        message: `长方形面积错误：长${length}，宽${width}，面积应该是${expectedArea}，但答案是${answer}`
      };
    }
    
    // 正方形面积
    const squareMatch = question.stem.match(/边长.*?(\d+(?:\.\d+)?)\s*(?:厘米|米|cm|m)/);
    if (squareMatch) {
      const side = parseFloat(squareMatch[1]);
      const answer = parseFloat(question.answer[0]);
      const expectedArea = side * side;
      
      if (Math.abs(answer - expectedArea) < 0.01) {
        return { valid: true };
      }
      
      return {
        valid: false,
        message: `正方形面积错误：边长${side}，面积应该是${expectedArea}，但答案是${answer}`
      };
    }
    
    return { valid: true, message: '无法解析题目' };
  },
  
  // 周长计算验证
  perimeter: (question) => {
    // 长方形周长
    const rectMatch = question.stem.match(/长.*?(\d+(?:\.\d+)?)\s*(?:厘米|米|cm|m).*?宽.*?(\d+(?:\.\d+)?)\s*(?:厘米|米|cm|m)/);
    if (rectMatch && question.stem.includes('周长')) {
      const length = parseFloat(rectMatch[1]);
      const width = parseFloat(rectMatch[2]);
      const answer = parseFloat(question.answer[0]);
      const expectedPerimeter = 2 * (length + width);
      
      if (Math.abs(answer - expectedPerimeter) < 0.01) {
        return { valid: true };
      }
      
      return {
        valid: false,
        message: `长方形周长错误：长${length}，宽${width}，周长应该是${expectedPerimeter}，但答案是${answer}`
      };
    }
    
    return { valid: true, message: '无法解析题目' };
  },
  
  // 平均数验证
  average: (question) => {
    const numbers = question.stem.match(/\d+(?:\.\d+)?/g);
    if (!numbers || numbers.length < 2) return { valid: true, message: '无法解析题目' };
    
    if (question.stem.includes('平均') && !question.stem.includes('求')) {
      const nums = numbers.slice(0, -1).map(n => parseFloat(n));
      const answer = parseFloat(question.answer[0]);
      const expectedAvg = nums.reduce((a, b) => a + b, 0) / nums.length;
      
      if (Math.abs(answer - expectedAvg) < 0.01) {
        return { valid: true };
      }
      
      return {
        valid: false,
        message: `平均数错误：数字${nums.join(',')}，平均数应该是${expectedAvg.toFixed(2)}，但答案是${answer}`
      };
    }
    
    return { valid: true, message: '无法解析题目' };
  },
};

// 检查题目完整性
function checkQuestionIntegrity(question, topicId, index) {
  const issues = [];
  
  // 检查必需字段
  if (!question.stem || question.stem.trim() === '') {
    issues.push('题干为空');
  }
  
  if (!question.answer || question.answer.length === 0) {
    issues.push('答案为空');
  }
  
  if (!question.solution || question.solution.trim() === '') {
    issues.push('解析为空');
  }
  
  if (!question.difficulty || question.difficulty < 1 || question.difficulty > 5) {
    issues.push('难度值无效');
  }
  
  // 检查答案格式
  if (question.answer) {
    question.answer.forEach((ans, i) => {
      if (ans === null || ans === undefined || ans === '') {
        issues.push(`答案[${i}]为空`);
      }
    });
  }
  
  // 检查题干长度
  if (question.stem && question.stem.length < 10) {
    issues.push('题干过短，可能不完整');
  }
  
  if (question.stem && question.stem.length > 500) {
    issues.push('题干过长，可能有问题');
  }
  
  // 检查解析长度
  if (question.solution && question.solution.length < 10) {
    issues.push('解析过短，可能不够详细');
  }
  
  return issues;
}

// 验证单个题目
function verifyQuestion(question, topicId, index) {
  results.total++;
  
  const issues = checkQuestionIntegrity(question, topicId, index);
  
  if (issues.length > 0) {
    results.warnings++;
    results.warnings.push({
      topic: topicId,
      index: index + 1,
      issues: issues,
      question: question.stem.substring(0, 50) + '...'
    });
  }
  
  // 根据题型选择验证器
  let verifier = null;
  if (topicId.includes('鸡兔同笼')) {
    verifier = mathVerifiers.chickenRabbit;
  } else if (topicId.includes('行程')) {
    verifier = mathVerifiers.distance;
  } else if (topicId.includes('面积')) {
    verifier = mathVerifiers.area;
  } else if (topicId.includes('周长')) {
    verifier = mathVerifiers.perimeter;
  } else if (topicId.includes('平均数')) {
    verifier = mathVerifiers.average;
  }
  
  // 执行数学验证
  if (verifier) {
    try {
      const result = verifier(question);
      if (!result.valid) {
        results.failed++;
        results.errors.push({
          topic: topicId,
          index: index + 1,
          error: result.message,
          question: question.stem,
          answer: question.answer
        });
      } else {
        results.passed++;
      }
    } catch (error) {
      results.warnings++;
      results.warnings.push({
        topic: topicId,
        index: index + 1,
        issues: [`验证器执行错误: ${error.message}`],
        question: question.stem.substring(0, 50) + '...'
      });
    }
  } else {
    results.passed++;
  }
}

// 加载并验证所有题目
async function verifyAllQuestions() {
  console.log('🔍 开始验证题库...\n');
  
  const questionsDir = path.join(__dirname, '../../questions');
  const primaryDir = path.join(questionsDir, 'primary-school');
  const middleDir = path.join(questionsDir, 'middle-school');
  
  // 验证小学题目
  console.log('📚 验证小学题目...');
  const primaryFiles = fs.readdirSync(primaryDir).filter(f => f.endsWith('.ts'));
  for (const file of primaryFiles) {
    const topicId = file.replace('.ts', '');
    console.log(`  检查: ${topicId}`);
    
    try {
      const content = fs.readFileSync(path.join(primaryDir, file), 'utf-8');
      const questions = eval(content.match(/export const questions.*?=\s*(\[[\s\S]*?\]);/)[1]);
      
      questions.forEach((q, i) => verifyQuestion(q, topicId, i));
    } catch (error) {
      console.error(`  ❌ 加载失败: ${error.message}`);
    }
  }
  
  // 验证初中题目
  console.log('\n📚 验证初中题目...');
  const middleFiles = fs.readdirSync(middleDir).filter(f => f.endsWith('.ts'));
  for (const file of middleFiles) {
    const topicId = file.replace('.ts', '');
    console.log(`  检查: ${topicId}`);
    
    try {
      const content = fs.readFileSync(path.join(middleDir, file), 'utf-8');
      const questions = eval(content.match(/export const questions.*?=\s*(\[[\s\S]*?\]);/)[1]);
      
      questions.forEach((q, i) => verifyQuestion(q, topicId, i));
    } catch (error) {
      console.error(`  ❌ 加载失败: ${error.message}`);
    }
  }
  
  // 生成报告
  generateReport();
}

// 生成验证报告
function generateReport() {
  console.log('\n' + '='.repeat(60));
  console.log('📊 验证报告');
  console.log('='.repeat(60));
  console.log(`总题目数: ${results.total}`);
  console.log(`✅ 通过: ${results.passed} (${(results.passed/results.total*100).toFixed(1)}%)`);
  console.log(`❌ 错误: ${results.failed} (${(results.failed/results.total*100).toFixed(1)}%)`);
  console.log(`⚠️  警告: ${results.warnings} (${(results.warnings/results.total*100).toFixed(1)}%)`);
  console.log('='.repeat(60));
  
  // 显示错误
  if (results.errors.length > 0) {
    console.log('\n❌ 发现的数学错误：\n');
    results.errors.forEach((err, i) => {
      console.log(`${i + 1}. ${err.topic} - 第${err.index}题`);
      console.log(`   题目: ${err.question.substring(0, 60)}...`);
      console.log(`   答案: ${err.answer}`);
      console.log(`   错误: ${err.error}`);
      console.log('');
    });
  }
  
  // 显示警告
  if (results.warnings.length > 0 && results.warnings.length <= 20) {
    console.log('\n⚠️  发现的警告：\n');
    results.warnings.slice(0, 20).forEach((warn, i) => {
      console.log(`${i + 1}. ${warn.topic} - 第${warn.index}题`);
      console.log(`   题目: ${warn.question}`);
      console.log(`   问题: ${warn.issues.join(', ')}`);
      console.log('');
    });
    
    if (results.warnings.length > 20) {
      console.log(`   ... 还有 ${results.warnings.length - 20} 个警告未显示\n`);
    }
  }
  
  // 保存详细报告
  const reportPath = path.join(__dirname, '../verification-report.json');
  fs.writeFileSync(reportPath, JSON.stringify(results, null, 2));
  console.log(`\n📄 详细报告已保存到: ${reportPath}\n`);
}

// 运行验证
verifyAllQuestions().catch(console.error);

